package moplayer;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;


public class ScaleFiller {

	public static int[] minorIntervals = {0, 2, 3, 5, 7, 8, 10, 12};
	public static int[] majorIntervals = {0, 2, 4, 5, 7, 9, 11, 12};
	
	public static int[] notes = {60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71};
	
	public static int[] arpeggioCrescenteMeta = {0, 2, 5, 8};
	public static int[] arpeggioDecrescenteMeta = {8, 5, 2 ,0};
	
	public HashMap<String, SortedSet<Integer>> scales;
	
	public ScaleFiller(){
		scales = new HashMap<String, SortedSet<Integer>>();
		fillScales();
	}
	
	private void fillScales(){
		for (int i = 0; i < notes.length; i++) {
			SortedSet<Integer> set = new TreeSet<Integer>();
			int currentNote = notes[i];
			for (int j = 0; j < majorIntervals.length; j++) {
				set.add(currentNote + majorIntervals[j] - 24);
				set.add(currentNote + majorIntervals[j] - 12);
				set.add(currentNote + majorIntervals[j]);
				set.add(currentNote + majorIntervals[j] + 12);
				set.add(currentNote + majorIntervals[j] + 24);
			}
			scales.put(createKey(currentNote, "major"), set);
			
			set = new TreeSet<Integer>();
			for (int j = 0; j < minorIntervals.length; j++) {
				set.add(currentNote + minorIntervals[j] - 24);
				set.add(currentNote + minorIntervals[j] - 12);
				set.add(currentNote + minorIntervals[j]);
				set.add(currentNote + minorIntervals[j] + 12);
				set.add(currentNote + minorIntervals[j] + 24);
			}
			scales.put(createKey(currentNote, "minor"), set);
		}
	}
	
	private String createKey(int note, String mode){
		return note + "." + mode;
	}

	public static Integer getNote(String key){
		return Integer.parseInt(key.split(".")[0]);
	}
	
	public static String getMode(String key){
		return key.split(".")[1];
	}
	
	public String getClosestScale(int[] sampleNotes){
		Set<Integer> sampleNotesSet = new HashSet<Integer>();
		for (int i = 0; i < sampleNotes.length; i++) {
			sampleNotesSet.add(sampleNotes[i]);
		}
		HashMap<String, Integer> count = new HashMap<String, Integer>();
		Set<String> keys = this.scales.keySet();
		for (String key : keys) {
			Set<Integer> sampleScale = this.scales.get(key);
			Set<Integer> intersection = SetOperations.intersection(sampleNotesSet, sampleScale);
			count.put(key, intersection.size());
		}
		Set<String> filledCountKey = count.keySet();
		int maxValue = 0;
		String chosen = "";
		for (String key : filledCountKey) {
			Integer integer = count.get(key);
			if(integer > maxValue){
				chosen = key;
				maxValue = integer;
			}
		}
		return chosen;
	}
	
	public static void main(String[] args) {
		ScaleFiller filler = new ScaleFiller();
		int[] sampleNotes = {60,63,68};
		String closestScale = filler.getClosestScale(sampleNotes);
		System.out.println(closestScale);
	}
	
}
